package com.android.progressdemo;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

import java.text.DecimalFormat;

public class TextBarView extends View {
    private final DecimalFormat df = new DecimalFormat("0.0");

    // 底部小箭头的高度，单位像素
    private float mArrowHeight;
    // 绘制文字
    private Paint paintInfoText;
    // 绘制百分比
    private Paint paintProgress;
    // 绘制小弹窗
    private Paint paintInfo;
    // 绘制小弹窗的边框
    private Paint paintInfoLine;
    // 小弹窗的轨迹对象
    private final Path path = new Path();
    // 当前百分比
    private float progress = 0;
    //左边文字的画笔
    private Paint leftPaint;
    //左边文字【可以左右添加空格增加左右距离】
    private String leftText = "";
    // 左边文字的颜色
    private int leftTextColor = Color.BLACK;
    // 左边文字的尺寸
    private float leftTextSize;
    //左边文字所占的宽度
    private float leftWidth;
    //左边文字宽度所占的百分比
    private float leftPercent = 0;
    //上下文
    private final Context mContext;
    //小弹窗距离上面的距离
    private float top;
    //小弹窗的文字的宽度
    private float infoTextWidth;
    //小弹窗的文字【可以左右添加空格增加左右距离】
    private String infoText = "";
    // 小弹窗文字的颜色
    private int infoTextColor = Color.BLACK;
    // 小弹窗文字的尺寸
    private float infoTextSize;
    // 小箭头-等边三角形的边长的一半
    private float c;
    // 小弹窗左右圆弧对应圆的半径
    private float r;

    public TextBarView(Context context) {
        this(context, null);
    }

    public TextBarView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TextBarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        initAttrs(mContext, attrs);
        init();

        setBackgroundColor(Color.GRAY);
    }

    private void initAttrs(Context context, AttributeSet attrs) {
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.TextBarView);
        this.leftText = array.getString(R.styleable.TextBarView_left_text);
        this.leftText = TextUtils.isEmpty(this.leftText) ? "" : this.leftText;
        // 限制左边文字最大10个字符
        if (this.leftText.length() > 10) {
            this.leftText = leftText.substring(0, 10) + "...";
        }
        leftTextColor = array.getColor(R.styleable.TextBarView_left_text_color, Color.BLACK);
        leftTextSize = array.getDimension(R.styleable.TextBarView_left_text_size, Utils.sp2px(mContext, 16));//默认16sp

        this.infoText = array.getString(R.styleable.TextBarView_info_text);
        this.infoText = TextUtils.isEmpty(this.infoText) ? "" : this.infoText;
        // 限制左边文字最大10个字符
        if (this.infoText.length() > 10) {
            this.infoText = infoText.substring(0, 10) + "...";
        }
        infoTextColor = array.getColor(R.styleable.TextBarView_info_text_color, Color.BLACK);
        infoTextSize = array.getDimension(R.styleable.TextBarView_info_text_size, Utils.sp2px(mContext, 16));//默认16sp
        array.recycle();
    }


    private void init() {
        // 顶部距离
        top = Utils.dp2px(mContext, 1);
        mArrowHeight = Utils.dp2px(mContext, 5);

        paintInfoText = new Paint();
        paintInfoText.setAntiAlias(true);
        paintInfoText.setColor(infoTextColor);
        paintInfoText.setTextSize(infoTextSize);

        leftPaint = new Paint();
        leftPaint.setAntiAlias(true);
        leftPaint.setColor(leftTextColor);
        leftPaint.setTextSize(leftTextSize);

        paintInfo = new Paint();
        paintInfo.setAntiAlias(true);
        // 弹窗的背景色
        paintInfo.setColor(Color.parseColor("#C87A7C"));
        paintInfo.setStyle(Paint.Style.FILL);
        // 弹窗的背景色的透明度
        paintInfo.setAlpha(100);

        paintInfoLine = new Paint();
        paintInfoLine.setAntiAlias(true);
        paintInfoLine.setColor(Color.RED);
        paintInfoLine.setStyle(Paint.Style.STROKE);

        paintProgress = new Paint();
        paintProgress.setAntiAlias(true);
        paintProgress.setColor(Color.RED);
        paintProgress.setTextSize(Utils.sp2px(mContext, 16));
        paintProgress.setTypeface(Typeface.DEFAULT_BOLD);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        leftWidth = leftPaint.measureText(leftText, 0, leftText.length());
        leftPercent = leftWidth / w * 100;
        if (leftPercent > 100) leftPercent = 100;
        c = (float) (Math.tan(30 * Math.PI / 180) * mArrowHeight);
        r = (h - mArrowHeight * 2) / 2;
        infoTextWidth = paintInfoText.measureText(infoText, 0, infoText.length());
        invalidate();
    }


    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        canvas.drawLine(0,getHeight()/2,getWidth(),getHeight()/2,paintInfoText);

        Paint.FontMetricsInt fontMetricsInt = leftPaint.getFontMetricsInt();
        float dy = (fontMetricsInt.bottom - fontMetricsInt.top) / 2f - fontMetricsInt.bottom;
        float baseLine = (getHeight() - mArrowHeight) / 2f + dy;
        canvas.drawText(leftText, 0, baseLine, leftPaint);

        // 活动范围 【r+c, getWidth-r-c】
        float minX = leftWidth + r + c;

        path.reset();
        if (progress < leftPercent) {
            drawInfoWindow(canvas, minX, 0);
            return;
        }

        float progress2 = progress - leftPercent;
        float maxX = getWidth() - r - c;
        float bottomWidth = maxX - minX;
        float offsetMax = getTextWidth() - 2 * c;
        float offset = progress2 * offsetMax / (100 - leftPercent);

        float x = progress2 * bottomWidth / (100 - leftPercent);
        float currentXArrow = x + minX;
        drawInfoWindow(canvas, currentXArrow, offset);

    }

    /**
     * 获取小弹窗里文字的宽度
     *
     * @return 宽度，单位像素
     */
    private float getTextWidth() {
        String text2 = getText2();
        float textWidth2 = paintInfoText.measureText(text2, 0, text2.length());
        return infoTextWidth + textWidth2;
    }

    /**
     * 获取小弹窗里的百分比
     *
     * @return 百分比
     */
    private String getText2() {
        return df.format(progress)  +" %   ";
    }

    /**
     * 绘制小弹窗
     *
     * @param canvas        画布
     * @param currentXArrow 当前小箭头的X坐标
     * @param offset        左边宽度偏移量
     */
    private void drawInfoWindow(Canvas canvas, float currentXArrow, float offset) {
        float textWidth = getTextWidth();

        //第一步：从小箭头的底部开始作为起点
        path.moveTo(currentXArrow, getHeight());
        //第二步：往左画一条直线
        path.lineTo(currentXArrow - c, getHeight() - mArrowHeight);
        float leftX = currentXArrow - c - offset;
        float rightX = leftX + textWidth;

        float centerX = leftX + (rightX - leftX) / 2;
        //第三步：往左画一条直线
        path.lineTo(leftX, getHeight() - mArrowHeight);
        //第四步：从左下方开始画一条圆弧【半圆】
        path.arcTo(new RectF(leftX - r, top, leftX + r, getHeight() - mArrowHeight), 90, 180);
        //第五步：从左往右移动
        path.lineTo(rightX, top);
        //第六步：在右边画一条圆弧【半圆】
        path.arcTo(new RectF(rightX - r, top, rightX + r, getHeight() - mArrowHeight), -90, 180);
        //第七步：从下面回到小箭头的位置
        path.lineTo(currentXArrow + c, getHeight() - mArrowHeight);
        //第八步：闭合
        path.close();
        //绘制轨迹-填充
        canvas.drawPath(path, paintInfo);
        //绘制轨迹-边框
        canvas.drawPath(path, paintInfoLine);

        //绘制文字
        float textX = centerX - textWidth / 2;
        Paint.FontMetricsInt fontMetricsInt = paintInfoText.getFontMetricsInt();
        float dy1 = (fontMetricsInt.bottom - fontMetricsInt.top) / 2f - fontMetricsInt.bottom;
        float baseLine1 = (getHeight() - mArrowHeight) / 2f + dy1;
        canvas.drawText(infoText, textX, baseLine1, paintInfoText);

        //绘制百分比
        Paint.FontMetricsInt fontMetricsInt2 = paintProgress.getFontMetricsInt();
        float dy2 = (fontMetricsInt2.bottom - fontMetricsInt2.top) / 2f - fontMetricsInt2.bottom;
        float baseLine2 = (getHeight() - mArrowHeight) / 2f + dy2;
        canvas.drawText(getText2(), textX + infoTextWidth, baseLine2, paintProgress);
    }

    /**
     * 设置当前百分比
     *
     * @param progress 百分比
     */
    public void setProgress(float progress) {
        this.progress = progress;
        invalidate();
    }

    /**
     * 设置当前百分比，带动画
     *
     * @param p 百分比
     */
    public void setProgressWithAnim(float p) {
        ValueAnimator animator = ValueAnimator.ofFloat(0, p).setDuration(1500);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                progress = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        animator.start();
    }
}
